<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
        <style>
            html,
            body {
                padding: 0;
                margin: 0;
                width: 100%;
                height: 100%;
            }

            #app {
                width: 100%;
                height: 100%;
                background: black;
            }

            .container {
                width: 100%;
                height: 100%;
                box-sizing: border-box;
                display: flex;
            }

            #canvas {
                border: 1px solid #fff;
                background-color: #000;
                margin: auto;
            }
        </style>
    </head>

    <body onclick="changePic()">
        <div id="app">
            <div class="container">
                <canvas id="canvas" width="800" height="800"></canvas>
            </div>
        </div>

        <script>
            const canvas = document.getElementById('canvas')
            const ctx = canvas.getContext("2d")
            let pointArr = []
            let pos_h_w = []
            let picIndex = 0
            let picList = ["./imgs/剪鹿.png", './imgs/女神.png']
            let imgW = 600
            let imgH = null
            const img = new Image();
            let imgData = null
            img.src = picList[picIndex]

            img.onload = function () {
                imgH = imgW * (img.height / img.width)
                console.log(999, imgH, imgW);
                ctx.drawImage(img, 0, 0, imgW, imgH);
                imgData = ctx.getImageData(0, 0, imgW, imgH).data;
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                pointInit(imgData)
                move()
            }

            class Point {
                constructor(size, w, h) {
                    this.orw = w
                    this.orh = h
                    this.x = Math.random() * canvas.width
                    this.y = Math.random() * canvas.height
                    this.size = size
                    this.w = w
                    this.h = h
                    this.spx = (w - this.x) / 2 / 20
                    this.spy = (h - this.y) / 2 / 20
                }
                update() {
                    this.spx = (this.w - this.x) / 2 / 20
                    this.spy = (this.h - this.y) / 2 / 20
                    if (Math.abs(this.w - this.x) <= Math.abs(this.spx)) {
                        this.x = this.w
                    } else {
                        this.x += this.spx
                    }
                    if (Math.abs(this.h - this.y) <= Math.abs(this.spy)) {
                        this.y = this.h
                    } else {
                        this.y += this.spy
                    }
                }
                rander() {
                    ctx.beginPath();
                    ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2)
                    ctx.fillStyle = '#fff';
                    ctx.fill()
                    ctx.closePath();
                }

            }

            function pointInit(imgData) {
                const gap = 4;
                let pushIndex = 0;
                for (let h = 0; h < imgH; h += gap) {
                    for (let w = 0; w < imgW; w += gap) {
                        let position = (imgW * h + w) * 4;
                        let r = imgData[position], g = imgData[position + 1], b = imgData[position + 2];
                        if (r + g + b === 0) {
                            let pushPoint = pos_h_w[picIndex - 1] && pos_h_w[picIndex - 1][pushIndex++]
                            if (pushPoint) {
                                pushPoint.w = w;
                                pushPoint.h = h;
                                pointArr.push(pushPoint)
                            } else {
                                pointArr.push(new Point(1, w, h))
                            }

                        }
                    }
                }
                pos_h_w.push(pointArr)
            }

            function move() {
                ctx.clearRect(0, 0, canvas.width, canvas.height)
                pointArr.forEach(point => {
                    point.update()
                    point.rander()
                })
                requestAnimationFrame(move)
            }

            // 散开聚合
            function changePic() {
                picIndex++;
                picIndex = picIndex % picList.length
                img.src = picList[picIndex]
            }
            // 更换图片
        </script>
    </body>

</html>